Mirko in Slavko sta postala navdušena nad vsemi oblikami števil, zaporedij in podobno.
Potem ko sta se naveličala preštevati, ali število zrn v krogih
pri sončnici res ustreza Fibonaccijevemu
zaporedju, sta naletela na funkcijo, ki naj bi vrnila seznam, ki vsebuje prvih
n
vrstic Pascalovega (binomskega) trikotnika
(vrstica naj bo spet seznam).
def trikotnik(n):
'''Vrne n vrstic Pascalovega trikotnika'''
celota = [[1]] # bo tole prav?
zgoraj = []
j = 0
while j <= n: # tu je nekaj narobe
i = 1
nova = [1]
while i < len(zgoraj):
nova = [zgoraj[i - 1] + zgoraj[i]] # hm, tole ...
i = i + 1
zgoraj = nova + [1]
celota = celota + zgoraj # tudi tukaj
j = j + 1
return celota
Žal (kot običajno) ima nekaj napak. Odpravi ji ... Na srečo je Mirko že intenzivno preiskušal funkcijo in odkril štiri možna mesta napak (glej oznake v kodi). Slavko pravi, da je Mirko pretiraval in da so napake zagotovo tri.
def trikotnik(n): '''Vrne n vrstic Pascalovega trikotnika''' celota = [[1]] # začetna vrstica zgoraj = [] # prejšnja vrstica j = 0 while j < n - 1: i = 1 nova = [1] # sestavimo novo vrstico while i < len(zgoraj): # na osnovi prejšnje sestavimo novo nova += [zgoraj[i - 1] + zgoraj[i]] # dodamo vsoto zgornjih členov i = i + 1 zgoraj = nova + [1] # še zaključna enka - in si jo zapomnimo za naslednji korak celota = celota + [zgoraj] # dodamo v trikotnik j = j + 1 return celota
Številka EMŠO je sestavljena iz trinajst števk v obliki DDMMLLL50NNNX, pri čemer je DDMMLLL rojstni datum, 50 je koda registra, NNN je zaporedna številka in X kontrolna številka. Trimestna številka, NNN, je med 000 in 499 za moške ter med 500 in 999 za ženske.
Napiši funkcijo je_zenska(emso)
, ki za številko EMŠO, ki jo podamo kot niz,
vrne True
, če pripada ženski in False
, če moškemu.
Primer:
>>> je_zenska('0505913509174')
True
>>> je_zenska('2109913502875')
False
def je_zenska(emso): '''Ali EMSO predstavlja žensko''' return emso[9] >= "5" # od 000 do 499 velja, da na 9. mestu stoji št. med 0 in 4 # od 500 do 999 velja, da na 9. mestu stoji št. med 5 in 9
Za okroglo mizo sedijo gosti. Nekateri so srečni, drugi ne. Konkretno: srečni so moški, ki sedijo med dvema ženskama in ženske, ki sedijo med dvema moškima. Razpored gostov podamo s seznamom njihovih številk EMŠO.
Napiši funkcijo stevilo_srecnezev(razpored)
, ki prejme takšen seznam in vrne število srečnih gostov.
Pazi: Ker je miza okrogla, sedi prvi gost poleg zadnjega. Če sedita moški in ženska sama za okroglo mizo, seveda nista srečneža.
Primer:
>>> stevilo_srecnezev(['0903912505707', '0110913506472', '2009956506012','1102946502619', '1902922506199', '2602930503913',
'0204940508783','1602960505003', '0207959502025', '0207962509545'])
4
>>> stevilo_srecnezev(['0702948501362', '1505987508785'])
0
def stevilo_srecnezev(razpored): '''Koliko moških sedi med dvema ženskama, oz. koliko žensk sedi med dvema moškima''' srecnih = 0 n = len(razpored) if n < 3: # če nimamo vsaj tri osebe, ni srečnih! return 0 for i in range(n): pred = razpored[i-1] # sedez pred i-tim sedezom tren = razpored[i] # i-ti sedez nasl = razpored[(i+1) % n] # sedez za i-tim sedezom if je_zenska(pred) != je_zenska(tren) != je_zenska(nasl): # ce je na sredini moski, mora srecnih += 1 # imeti levo in desno zensko in obratno return srecnih
Jeremija ves svoj prosti čas (torej ko ne spi, ko ne toži nad bolečinami, skratka kako minuto na dan) preživi kot moderator na nekem manj znanem forumu, ki ima kar lepo število registriranih uporabnikov, vendar večina med njimi piše same neumnosti. Med takimi je še posebno dejaven Tomaž Majer. Če se zdi Jeremiji objava žaljiva, jo nemudoma zbriše. Če objava na forumu ni žaljiva, ampak je le precej neumna, pa naredi naslednje: Vse samoglasnike odstrani iz besedila in jih (v enakem vrstnem redu) doda nazaj na konec. Na primer sporočilo:
Banana je najboljša! Izjemno dobra je tudi v kombinaciji z Nutelo!
postane
Bnn j njbljš! zjmn dbr j td v kmbncj z Ntl!aaaeaoaIeooaeuioiaiiueo
Takó besedilo postane težko berljivo in večina bralcev ga ignorira. Če pa se najde kdo, ki ga vsebina resnično zanima, lahko z nekaj truda razvozla vsebino sporočila.
Opisana transformacija besedila je znana pod imenom disemvoweling.
Napišite funkcijo prviSamoglasnik(niz)
, ki kot argument dobi niz niz
in vrne položaj (indeks) prvega samoglasnika v danem nizu. Če v nizu ni
samoglasnika, vrni -1
>>> prviSamoglasnik('Krščen matiček!')
4
def prviSamoglasnik(niz): '''vrne položaj (indeks) prvega samoglasnika v danem nizu''' samoglasniki = "aeiouAEIOU" kje = 0 for znak in niz: if znak in samoglasniki: # takoj pri prvem bomo zaključili zadevo return kje kje += 1 return -1 # ni ga bilo def prviSamoglasnikDieHardPython(niz): #dieHard Pythonovci bi seveda zadevo napisali takole samoglasniki = "aeiou" return min(niz.index(c) for c in samoglasniki + samoglasniki.upper() if c in niz)
Napišite funkcijo disemvowel(sporocilo)
, ki kot argument prejme niz
sporocilo
. Funkcija naj sestavi in vrne nov niz, ki ga dobi iz niza
sporocilo
tako, da vse samoglasnike prestavi na konec niza.
>>> disemvowel('Banana je dobra!')
'Bnn j dbr!aaaeoa'
def disemvowel(sporocilo): '''desemvowlanje sporočila''' brez = '' # niz brez samoglasnika samoglasniki = '' # vsi samoglasniki iz niza for c in sporocilo: if c in 'aeiouAEIOU': # gre za samoglasnik samoglasniki += c else: #"običajni" znak brez += c return brez + samoglasniki #zlepimo v pravem redu
Včasih pa želimo sporočilo dešifrirati, saj nas zanima njegova vsebina.
Ta naloga je vse prej kot enostavna, saj ne vemo kam točno je treba vriniti
izgnane samoglasnike. Sporočilo 'Bnn j dbr!aaaeoa'
bi lahko dešifrirali
tudi kot 'Banna ja debora!'
, kot 'Bnana aje dobar!'
ipd.
Bob Rock je na mesta v besedilu, kjer predvideva, da bi morali stati
samoglasniki, vstavil znake '*'
(zvezdica). V sporočilu zvezdica nikoli
ne bo imela drugega pomena. Prav tako bo število samoglasnikov enako številu
zvezdic in vsi samoglasniki bodo na koncu niza.
Napišite funkcijo razveljaviDisemvowel(niz)
, ki bo zvezdice v nizu
nadomestila s samoglasniki, ki se v nizu niz
nahajajo na koncu. Zgled:
>>> razveljaviDisemvowel('B*n*n* j* d*br*!aaaeoa')
'Banana je dobra!'
def razveljaviDisemvowel(niz): '''zvezdice v disemvowlanem nizu nadosmesti s samoglasniki s konca niza''' stZvezdic = niz.count('*') #da bomo vedeli, kje se začno samoglasniki if stZvezdic == 0: # ni kaj delati return niz samoglasniki = niz[-stZvezdic:] # odrežemo ustrezen del niza sporocilo = '' stevec = 0 # kje v nizu samogalsnikov smo for c in niz[:-stZvezdic]: # pregledamo le del niza brez končnih samoglasnikov if c == '*': # zvezdico nadomestimo z ustreznim samoglasnikom sporocilo += samoglasniki[stevec] stevec += 1 # premaknemo se naprej po samoglasnikih else: sporocilo += c return sporocilo
Učenci so se v šoli v naravi med prostim časom zabavali z različnimi besednimi igrami.
Ena izmed njih je bila ugibanje pomena čudnih besed. Pravilo je bilo, da so si zamišljali besede,
ki vsebujejo črkovno zvezo 'pa' in jo nadomestili z zvezo 'cveti'.
Tako so nastajale smešne besede kot na primer: cvetiprika, cveticvetigaj, nacvetidalec itd...
Sestavi funkcijo cvetoceBesede(niz)
, ki bo vrnila pravi pomen teh besed.
Pri tem ne smeš uporabiti funkcije replace!
Na primer:
>>>cvetoceBesede('cveticvetigaj')
papagaj
def cvetoceBesede(niz): '''izloči 'cveti' in nadomesti s 'pa' ''' pravaBeseda = '' i = 0 while i < len(niz) - 4: if niz[i:i+5] == 'cveti': # jemljemo po 5 znakov pravaBeseda += 'pa' # prvi dve zaporedni črki iz niza 'cveti' zamenja z 'pa', ostale tri pa izbriše i += 5 else: pravaBeseda += niz[i] i += 1 # prepišemo še mnorebitni preostanek while i < len(niz): pravaBeseda += niz[i] i += 1 return pravaBeseda def cvetoceBesedeV1(niz): '''izloči 'cveti' in nadomesti s 'pa' uporaba ukaza del ''' pravaBeseda='' if 'cveti' in niz: #ugotovi, če je v besedi besedna zveza "cveti" sezCvet=list(niz)#niz spremeni v seznam i=0 while i<len(sezCvet)-4: # prvi dve zaporedni črki iz niza 'cveti' zamenja z 'pa', ostale tri pa izbriše, nato pregleda še ostanek seznama if sezCvet[i:i+5]==['c', 'v', 'e', 't', 'i']: sezCvet[i]='p' sezCvet[i+1]='a' del sezCvet[i+2:i+5] i+=1 pravaBeseda=''.join(sezCvet) #seznam zopet spremeni v niz in ga vrne else: return niz return pravaBeseda def cvetoceBesedev2(niz): '''izloči 'cveti' in nadomesti s 'pa' uporabimo replace ''' pravaBeseda = niz.replace('cveti', 'pa') return pravaBeseda def cvetoceBesedev3(niz): '''izloči 'cveti' in nadomesti s 'pa' uporabimo split in join ''' pravaBeseda = 'pa'.join(niz.split('cveti')) return pravaBeseda
V vasi Muhačevo so bili navdušeni pevci in so radi prepevali znano ljudsko: "Priletela muha na zid."
Besedilo pesmi je povsem enostavno, saj se v bistvu ves čas ponavlja isto besedilo.
Posebnost pesmi je v tem, da se najprej poje tako, da se vsi samoglasniki spremenijo v a, nato v e in tako naprej,
dokler ne pridejo na vrsto vsi samoglasniki (a,e,i,o,u).
Sestavi funkcijo muha(niz)
, ki bo vpisano besedo ali besedno zvezo spremenila v seznam besed,
v katerih bodo najprej vsi samoglasniki a, nato e in še i, o in u.
Beseda je napisana z malimi tiskanimi črkami.
Na primer:
>>> muha('trobentica')
['trabantaca', 'trebentece', 'tribintici', 'trobontoco', 'trubuntucu'].
def muha(niz): '''vrne seznam besed, v katerih so spremenjeni vsi samoglasniki najprej v a, nato v e in tako naprej''' vsiSamoglasniki = 'aeiou' seznamBesed = [] for samoglasnik in vsiSamoglasniki: # uporabimo vse samoglasnike novaBeseda = '' for znak in niz: # pregledamo vse znake v nizu if znak in vsiSamoglasniki: # če gre za poljuben samoglasnik novaBeseda += samoglasnik # dodamo trenutno 'aktivnega' else: novaBeseda += znak # sicer ga le prepišemo seznamBesed.append(novaBeseda) # beseda z ustreznim samoglasnikom return seznamBesed
Učiteljica je dala učencem nalogo naj napišejo tri besede tako,
da se bo vsaka črka v vseh treh besedah pojavila natanko enkrat.
Vsako novo pojavitev iste črke bo štela za napako. Torej, če se bo črka a pojavila
trikrat, bosta to dve napaki.
Sestavi funkcijo besede(niz)
, ki bo preštela napake in vrnila, koliko napak je učenec naredil.
Pri tem so besede ločene z vejicami, ki niso del besed, vsi ostali zanki pa so!
Na primer:
>>>besede('miza,miha,zima')
7
>>>besede('mimi,ali,gremo')
4
def besede(niz): '''funkcija prešteje, kolikokrat se posamezne črke pojavijo več kot enkrat''' koliko = 0 črke = '' # katere črke so se že pojavile for znak in niz: if znak != ',': # vejice ignoriramo if znak in črke: # znak se je pojavil že prej koliko += 1 else: črke += znak # nov znak return koliko
Lojzku je dolgčas, zato se igra z velikimi praznimi škatlami, ki se
nahajajo v skladišču, v katerem dela. Dimenzije škatel so shranjene v
seznamu trojic. Na primer, trojica (50, 100, 100)
predstavlja
škatlo, ki je visoka 50 cm ter široka in dolga 100 cm.
S trojicami delamo tako kot s seznami, le spremijati ne moremo elementov.
Torej tro[0]
nam da prvi element iz trojice. Seveda pa lahko trojko tudi
"razpakiramo"
vis, sir, dol = skatla
če je skatla
neka trojka.
Sestavite funkcijo stolp(skatle)
, ki vrne višino najvišjega
stolpa, ki ga lahko sestavimo iz škatel, ne da bi jih obračali.
Pri tem ni treba paziti na stabilnost stolpa.
Na primer
>>>stolp([(50, 100, 100), (60, 30, 50), (40, 40, 40)])
150
def stolp(skatle): '''Višina stolpa iz škatel, če škatle zlagamo po višini (prvi dimenziji)''' skupnaVišina = 0 for skatla in skatle: # pregledamo vse škatle visina, sirina, dolzina = skatla skupnaVišina += visina return skupnaVišina ##Dodatno znanje nam da krajši zapis rešitve: ##def stolp(skatle): ## return sum(v for v, _, _ in skatle)
Sestavite funkcijo najvisjiStolp(skatle)
, ki vrne višino najvišjega
stolpa, ki ga lahko sestavimo iz škatel, če jih lahko obračamo.
Pri tem še vedno ni treba paziti na stabilnost stolpa.
Na primer, najvišji tak stolp iz škatel z dimenzijami (50, 100, 100),
(60, 50, 50) in (40, 40, 40) bi imel višino 200 cm, saj bi prvo škatlo
prevrnili na bok.
def najvisjiStolp(skatle): '''Kako visok je lahko stolp, če lahko škatle obračamo''' višina = 0 for skatla in skatle: višina += max(skatla) # pobrali smo največjo dimenzijo return višina ##Dodatno znanje nam da krajši zapis rešitve: ##def najvisjiStolp(skatle): ## return sum(max(v, s, d) for v, s, d in skatle)
Sestavite funkcijo greNotri(skatla1, skatla2)
, ki vrne True
, če
škatlo skatla1
lahko obrnemo tako, da gre v škatlo skatla2
, torej
da so dimenzije prve škatle strogo manjše od dimenzij druge škatle.
def poVrsti(trojka): ''' uredimo trojko (a, b, c) po velikosti (t1, t2, t3) so torej premešani a, b, c da velja t1 <= t2 <= t3 ''' a, b, c = trojka mal = min(a, b, c) vel = max(a, b, c) sre = a + b + c - mal - vel return (mal, sre, vel) def greNotri(skatla1, skatla2): '''Ali lahko skatlo1 damo v skatlo2''' nova1 = poVrsti(skatla1) nova2 = poVrsti(skatla2) return nova1[0] < nova2[0] and \ nova1[1] < nova2[1] and \ nova1[2] < nova2[2]
Sestavite funkcijo prestej(niz)
, ki prešteje, koliko zašiljenih
oklepajev tj. '<'
in '>'
je v nizu niz
. Primer:
>>> prestej('<abc>>')
3
>>> prestej('a>> x<Y>x <<b')
6
>>> prestej('Koliko oklepajev > in < je v tem nizu?')
2
Pri tem ne smeš uporabiti vgrajene metode count
def prestej(niz): '''Koliko je v nizu zašiljenih oklepajev''' koliko = 0 iskaniZnaki = "><" for znak in niz: if znak in iskaniZnaki: koliko += 1 return koliko
Niz imenujemo ukleščen, če se začne z predklepajem '<'
, konča
z zaklepajem '>'
, vmes pa ni nobenega znaka za zašiljene oklepaje.
Na primer, niz '<Zunaj sije sonce.>'
je ukleščen niz.
Sestavite funkcijo uklescen(niz)
, ki preveri, ali je niz niz
ukleščen.
Primer:
>>> uklescen('<Zunaj sije sonce.>')
True
>>> uklescen('< <3 >')
False
>>> uklescen('Zunaj sije sonce.')
False
def uklescen(niz): '''Ali je niz ukleščen''' if len(niz) < 2: # niz je prekratek! return False return niz[0] == '<' and niz[-1] == '>' and prestej(niz) == 2
Sestavite funkcijo sklop(niz1, niz2)
, ki prejme dva ukleščena niza
in vrne ukleščeni niz, ki predstavlja njun sklop. (Kaj je to sklop, je
razvidno iz spodnjega primera.) Primer:
>>> sklop('<123>', '<456>')
'<123456>'
>>> sklop('<muca>', '<copatarica>')
'<mucacopatarica>'
def sklop(niz1, niz2): '''Sklopimo dva ukleščena niza''' return niz1[:-1] + niz2[1:]
Sestavite funkcijo razlomi(niz, s)
, ki kot argumenta prejme
ukleščeni niz niz
in seznam nenegativnih celih števil s
ter vrne
seznam ukleščenih nizov, ki imajo dolžine, naštete v seznamu s
,
in skupaj tvorijo niz niz
. Primer:
>>> razlomi('<Zunaj sije sonce.>', [2, 7, 8])
['<Zu>', '<naj sij>', '<e sonce.>']
>>> razlomi('<muca copatarica>', [4, 0, 11])
['<muca>', '<>', '< copatarica>']
Predpostavite lahko, da bo vsota števil v seznamu s
enaka dolžini
ukleščenega niza niz
(če ne štejemo zašiljenih oklepajev).
def razlomi(niz, s): '''Razlomi ukleščen niz na manjše koščke in vrne seznam koščkov''' rez = [] k = 1 # kje začnemo ukleščeni niz for dolzina in s: rez.append('<' + niz[k:k+dolzina] + '>') k += dolzina return rez
Sestavite funkcijo palindrom(niz)
, ki vrne True
kadar je niz
palindrom, in False
sicer.
def palindrom(niz): '''Ali je niz palindrom''' return niz == niz[::-1]
Sestavite funkcijo palindromHitro(niz)
, ki vrne True
kadar je niz
palindrom, in False
sicer.
Če niz ni palindrom, naj to ugotovi kar se da hitro (npr. Matija
očitno ni palibndrom,
saj M
ni enak a
def palindromHitro(niz): '''Ali je niz palindrom''' for ind in range(1, len(niz) // 2 + 1): if niz[ind - 1] != niz[-ind]: # neujemajoča se znaka return False #vsi pari se ujemajo return True
Pravimo, da je beseda skoraj palindrom, če ji je treba zbrisati natanko eno črko, da bi postala palindrom. Primer je beseda 'kolo', ki ji moramo zbrisati črko 'k', pa postane palindrom 'olo'.
Sestavite funkcijo skorajPalindrom(niz)
, ki preveri, ali je niz
skoraj palindrom. Vse znake (tudi presledke) v besedi obravnavamo enako.
def skorajPalindrom(niz): '''ALi je niz skoraj palindrom''' # za vsak i poskusimo izpustiti črko na i-tem mestu for i in range(len(niz)): # če smo dobili palindrom, končamo if palindrom(niz[:i] + niz[i + 1:]): return True # če je zanka prišla do konca, palindroma nismo našli return False
Sestavite funkcijo vsebuje(niz1, niz2)
, ki za parametra dobi dva niza
ter vrne True
, če in samo če je mogoče prvi niz dobiti tako, da v
drugi niz na poljubnih mestih vstavljamo dodatne znake. (povedano
drugače, če prvi niz vsebuje vse znake iz drugega niza v ustreznem
vrstnem redu).
Iz besede 'ROLA' lahko na primer z vrivanjem znakov dobimo besedo 'pRikOLicA'. Med velikimi in malimi tiskanimi črkami strogo ločujemo.
def vsebuje(niz1, niz2): '''Ali je niz2 vsebovan v nizu1''' # v spremenljivki indeksNiz2 hranimo indeks znaka v malem nizu, ki ga iščemo indeksNiz2 = 0 for znakNiz1 in niz1: # če smo našli znak na indeksu indeksNiz2, iščemo naslednjega if niz2[indeksNiz2] == znakNiz1: indeksNiz2 += 1 # če smo našli vse znake v malem nizu, končamo if indeksNiz2 == len(niz2): return True # če se zanka konča, vseh znakov nismo našli return False
Sestavite funkcijo besede(niz)
, ki sestavi in vrne seznam parov
indeksov (začetek, konec), ki določajo, kje v danem nizu se nahajajo
posamezne besede. Beseda je maksimalno zaporedje znakov, ki ne vsebuje
presledka.
>>> besede('Danes je lep dan, saj ne dežuje.')
[(0, 4), (6, 7), (9, 11), (13, 16), (18, 20), (22, 23), (25, 31)]
>>> besede(' abc abc abc ')
[(1, 3), (6, 8), (11, 13)]
def besede(stavek): '''Seznam položajev besed''' indeksi = [] # ali smo našli besedo, ali smo pri presledkih smo_v_besedi = False # zacetek trenutne besede zacetek = 0 for i in range(len(stavek)): z = stavek[i] # ta in prejšnji stavek lahko nadomestimo z enim # for i, z in enumerate(stavek): # če smo v besedi in najdemo presledek, dodamo njene indekse v seznam if smo_v_besedi and z == ' ': smo_v_besedi = False indeksi.append((zacetek, i - 1)) # če nismo v besedi in najdemo znak, začnemo z besedo elif not smo_v_besedi and z != ' ': smo_v_besedi = True zacetek = i # če smo na koncu zanke še vedno v besedi, ta beseda sega do konca if smo_v_besedi: indeksi.append((zacetek, len(stavek) - 1)) return indeksi